package com.lou.springboot.controller.admin;

import com.lou.springboot.common.ResultVO;
import com.lou.springboot.common.ResultVOUtil;
import com.lou.springboot.config.UploadConfig;
import com.lou.springboot.entity.Blog;
import com.lou.springboot.entity.BlogCategory;
import com.lou.springboot.enums.ResultEnum;
import com.lou.springboot.service.BlogCategoryService;
import com.lou.springboot.service.BlogService;
import com.lou.springboot.utils.JsonUtils;
import com.lou.springboot.utils.MyBlogUtils;
import com.lou.springboot.utils.PageUtil;
import com.lou.springboot.utils.RedisOperator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/admin")
public class BlogController extends BaseController{

    @Autowired
    private RedisOperator redisOperator;

    @Autowired
    private BlogService blogService;

    @Autowired
    private BlogCategoryService categoryService;

    @Autowired
    private UploadConfig uploadConfig;

    @GetMapping("/blogs/edit")
    public String edit(HttpServletRequest request) {
        request.setAttribute("path", "edit");
        List<BlogCategory> categories = categoryService.getAllCategories();
        request.setAttribute("categories", categories);
        return "admin/edit";
    }

    @GetMapping("/blogs")
    public String list(HttpServletRequest request){
        request.setAttribute("path","blogs");
        return "admin/blog";
    }

    @GetMapping("/blogs/list")
    @ResponseBody
    public ResultVO list(@RequestParam Map<String, Object> map){
        if (StringUtils.isEmpty(map.get("page")) || StringUtils.isEmpty(map.get("limit"))) {
            return ResultVOUtil.error(ResultEnum.PARAM_ERROR);
        }
        PageUtil pageUtil = new PageUtil(map);
        return ResultVOUtil.success(blogService.getBlogList(pageUtil));
    }

    /**
     * MarkDown编辑器内上传文件
     * @param request
     * @param response
     * @param file
     * @throws IOException
     * @throws URISyntaxException
     */
    @PostMapping("/blogs/md/uploadfile")
    public void uploadFileByEditormd(HttpServletRequest request,
                                     HttpServletResponse response,
                                     @RequestParam(name = "editormd-image-file", required = true)
                                             MultipartFile file) throws IOException, URISyntaxException {
//        String FILE_UPLOAD_DIC = "/home/project/upload/";//上传文件的默认url前缀，根据部署设置自行修改
//        String FILE_UPLOAD_DIC = "/projects/my_blog/upload/";
        final String FILE_UPLOAD_DIC = uploadConfig.getStaticAccessPath();
        String fileName = file.getOriginalFilename();
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //生成文件名称通用方法
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        Random r = new Random();
        StringBuilder tempName = new StringBuilder();
        tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
        String newFileName = tempName.toString();
        //创建文件
        File destFile = new File(FILE_UPLOAD_DIC + newFileName);
        String fileUrl = MyBlogUtils.getHost(new URI(request.getRequestURL() + "")) + "/upload_files/" + newFileName;
        File fileDirectory = new File(FILE_UPLOAD_DIC);
        try {
            if (!fileDirectory.exists()) {
                if (!fileDirectory.mkdir()) {
                    throw new IOException("文件夹创建失败,路径为：" + fileDirectory);
                }
            }
            file.transferTo(destFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            request.setCharacterEncoding("utf-8");
            response.setHeader("Content-Type", "text/html");
            response.getWriter().write("{\"resultCode\": 0,\"success\": 1, \"message\":\"success\",\"url\":\"" + fileUrl + "\"}");
        } catch (UnsupportedEncodingException e) {
            response.getWriter().write("{\"resultCode\": 9,\"success\":0}");
        } catch (IOException e) {
            response.getWriter().write("{\"resultCode\": 9,\"success\":0}");
        }
    }

    /**
     * 根据blogId获取文章详情
     * @param request
     * @param blogId
     * @return
     */
    @GetMapping("/blogs/info/{blogId}")
    public String getBlogDetailById(HttpServletRequest request,
                                      @PathVariable("blogId") Long blogId){
        request.setAttribute("path", "edit");
        if (blogId < 0) {
            return "error/error_400";
        }
        String blogDetailKey = ADMIN_BLOG_DETAIL_REDIS_PREFIX + blogId;
        String blogDetailRedisString = redisOperator.get(blogDetailKey);
        Blog blog;
        if (blogDetailRedisString == null) {
            blog = blogService.getBlog(blogId);
            redisOperator.set(blogDetailKey, JsonUtils.objectToJson(blog));
        } else {
            blog = JsonUtils.jsonToPojo(blogDetailRedisString, Blog.class);
        }
        if (blog == null) {
            return "error/error_404";
        }
        request.setAttribute("blog", blog);
        List<BlogCategory> categories = categoryService.getAllCategories();
        request.setAttribute("categories", categories);
        return "admin/edit";
    }

    /**
     * 更新文章详情
     * @param blogId
     * @param blogTitle
     * @param blogSubUrl
     * @param blogCategoryId
     * @param blogTags
     * @param blogContent
     * @param blogCoverImage
     * @param blogStatus
     * @param enableComment
     * @return
     */
    @PostMapping("/blogs/update")
    @ResponseBody
    public ResultVO update(@RequestParam("blogId") Long blogId,
                            @RequestParam("blogTitle") String blogTitle,
                            @RequestParam(name = "blogSubUrl", required = false) String blogSubUrl,
                            @RequestParam("blogCategoryId") Integer blogCategoryId,
                            @RequestParam("blogTags") String blogTags,
                            @RequestParam("blogContent") String blogContent,
                            @RequestParam("blogCoverImage") String blogCoverImage,
                            @RequestParam("blogStatus") Byte blogStatus,
                            @RequestParam("enableComment") Byte enableComment) {
        if (blogId == null || blogId < 1) {
            return ResultVOUtil.error("文章id不正确");
        }
        if (StringUtils.isEmpty(blogTitle)) {
            return ResultVOUtil.error("请输入文章标题");
        }
        if (blogTitle.trim().length() > 150) {
            return ResultVOUtil.error("标题过长");
        }
        if (StringUtils.isEmpty(blogTags)) {
            return ResultVOUtil.error("请输入文章标签");
        }
        if (blogTags.trim().length() > 150) {
            return ResultVOUtil.error("标签过长");
        }
        if (blogSubUrl.trim().length() > 150) {
            return ResultVOUtil.error("路径过长");
        }
        if (StringUtils.isEmpty(blogContent)) {
            return ResultVOUtil.error("请输入文章内容");
        }
        if (blogContent.trim().length() > 100000) {
            return ResultVOUtil.error("文章内容过长");
        }
        if (StringUtils.isEmpty(blogCoverImage)) {
            return ResultVOUtil.error("封面图不能为空");
        }
        Blog blog = new Blog();
        blog.setBlogId(blogId);
        blog.setBlogTitle(blogTitle);
        blog.setBlogSubUrl(blogSubUrl);
        blog.setBlogCategoryId(blogCategoryId);
        blog.setBlogTags(blogTags);
        blog.setBlogContent(blogContent);
        blog.setBlogCoverImage(blogCoverImage);
        blog.setBlogStatus(blogStatus);
        blog.setEnableComment(enableComment);

        if(blogService.updateBlog(blog).equals("success")){
            String blogDetailKey = ADMIN_BLOG_DETAIL_REDIS_PREFIX + blogId;
            redisOperator.del(blogDetailKey);
            return ResultVOUtil.success();
        } else {
            return ResultVOUtil.error("添加文章失败");
        }
    }

    /**
     * 新增博客文章
     * @param blogTitle
     * @param blogSubUrl
     * @param blogCategoryId
     * @param blogTags
     * @param blogContent
     * @param blogCoverImage
     * @param blogStatus
     * @param enableComment
     * @return
     */
    @PostMapping("/blogs/save")
    @ResponseBody
    public ResultVO save(@RequestParam("blogTitle") String blogTitle,
                         @RequestParam(name = "blogSubUrl", required = false) String blogSubUrl,
                         @RequestParam("blogCategoryId") Integer blogCategoryId,
                         @RequestParam("blogTags") String blogTags,
                         @RequestParam("blogContent") String blogContent,
                         @RequestParam("blogCoverImage") String blogCoverImage,
                         @RequestParam("blogStatus") Byte blogStatus,
                         @RequestParam("enableComment") Byte enableComment) {
        if (StringUtils.isEmpty(blogTitle)) {
            return ResultVOUtil.error("请输入文章标题");
        }
        if (blogTitle.trim().length() > 150) {
            return ResultVOUtil.error("标题过长");
        }
        if (StringUtils.isEmpty(blogTags)) {
            return ResultVOUtil.error("请输入文章标签");
        }
        if (blogTags.trim().length() > 150) {
            return ResultVOUtil.error("标签过长");
        }
        if (blogSubUrl.trim().length() > 150) {
            return ResultVOUtil.error("路径过长");
        }
        if (StringUtils.isEmpty(blogContent)) {
            return ResultVOUtil.error("请输入文章内容");
        }
        if (blogContent.trim().length() > 100000) {
            return ResultVOUtil.error("文章内容过长");
        }
        if (StringUtils.isEmpty(blogCoverImage)) {
            return ResultVOUtil.error("封面图不能为空");
        }
        Blog blog = new Blog();
        blog.setBlogTitle(blogTitle);
        blog.setBlogSubUrl(blogSubUrl);
        blog.setBlogCategoryId(blogCategoryId);
        blog.setBlogTags(blogTags);
        blog.setBlogContent(blogContent);
        blog.setBlogCoverImage(blogCoverImage);
        blog.setBlogStatus(blogStatus);
        blog.setEnableComment(enableComment);
        Object o = blogService.saveBlog(blog);

        if(o != null && o.getClass() != String.class){
            return ResultVOUtil.success(o);
        } else {
            return ResultVOUtil.error("添加文章失败");
        }
    }

    @PutMapping("/blogs/delete")
    @ResponseBody

    public ResultVO delete(@RequestBody Long[] blogIds) {
        if (blogIds.length < 1) {
            return ResultVOUtil.error(ResultEnum.PARAM_ERROR);
        }
        if (blogService.deleteBatch(blogIds)) {
            List<String> redisIds = Arrays.asList(blogIds)
                    .stream()
                    .map(id -> ADMIN_BLOG_DETAIL_REDIS_PREFIX + id)
                    .collect(Collectors.toList());
            redisOperator.del(redisIds);
            return ResultVOUtil.success();
        } else {
            return ResultVOUtil.error(ResultEnum.DELETE_FAILED);
        }
    }
}
